'use strict';
const {
	db_addOne,
	db_select,
	db_update,
	db_update_where,
	db_delete
} = require('../../model/index.js')
const db = uniCloud.database();
const dbCmd = db.command
const $ = db.command.aggregate
const tools = require("../../tools/index.js")
const alioss = require('../../oss/index.js')
const FileTypeTest = require('../../FileSuffixNameDictionary.js') // 文件后缀名配置表


// 创建文件夹接口
exports.APINewFolder = async function(body_data) {
	let {
		dir,
		UserInfo
	} = body_data;
	if (!dir) {
		return {
			msg: "参数错误"
		}
	};
	let FolderName = UserInfo.account + '/' + dir
	let {
		code
	} = await alioss.CreatFolder(FolderName)
	if (code == 200) {
		return {
			code: 200,
			msg: "创建文件夹成功~",
			dir: dir
		}
	}
	return {
		msg: "内部错误~",
		code: 500
	}
}
// 刷新sts接口
exports.APIFreshSts = async function(body_data) {
	let {
		UserInfo
	} = body_data
	let Sts = await alioss.assumeRole()
	return {
		code: 200,
		msg: '获取Sts成功~',
		data: Sts
	}
}
// 获取签证接口(上传文件用)
exports.APIGetMpUploadOssHelper = async function(body_data) {
	let {
		Token
	} = body_data;
	// 查询数据
	let res = await db_select("User", {
		Token
	})
	if (res.data.length == 0 || res.data === null) {
		return {
			code: 211,
			msg: "Token已过期,请重新登录"
		}
	}
	// 数据存在
	let ROOT_dir = null
	if (res.data.length >= 1) {
		ROOT_dir = res.data[0].account
	}


	const mpHelper = new alioss.MpUploadOssHelper({
		accessKeyId: alioss.ossConfig.accessKeyId,
		accessKeySecret: alioss.ossConfig.accessKeySecret,
		timeout: 1, // 限制参数的生效时间(单位：小时)。
		maxSize: 500, // 限制上传文件大小(单位：Mb)。
	});
	const params = mpHelper.createUploadParams();
	params['host'] = alioss.ossConfig.host
	params['ROOT_dir'] = ROOT_dir
	return {
		code: 200,
		msg: '获取签证成功~',
		params
	}
}
// 上传接口（初始化记录调用的）
exports.APIUploadFile = async function(body_data) {
	let {
		UserInfo,
		Token,
		fileId,
		fileName,
		filePath,
		fileSize,
		fileType
	} = body_data;
	if (!fileId || !fileName || !filePath || !fileSize || !fileType) {
		return {
			msg: "参数错误"
		}
	};
	
	// 判断用户的存储是否充足
	let ResSize= await getSpecifiedFileSizes({account:UserInfo.account})
	if(ResSize.data.CurrentSize + fileSize > UserInfo.UserStorageSpace) { return {code:204,msg:"您的存储空间已经达到上限，请购买存储空间！"} }
	
	
	// 查询Token 拿路径
	let res = await db_select("User", {
		Token
	})
	if (res.data.length == 0 || res.data === null) {
		return {
			code: 211,
			msg: "Token已过期,请重新登录"
		}
	}
	let ROOT_dir = null,
		uid = null,
		uploadTime = new Date()
	if (res.data.length >= 1) {
		ROOT_dir = res.data[0].account
		uid = res.data[0]._id
	}
	const mpHelper = new alioss.MpUploadOssHelper({
		accessKeyId: alioss.ossConfig.accessKeyId,
		accessKeySecret: alioss.ossConfig.accessKeySecret,
		timeout: 1, // 限制参数的生效时间(单位：小时)。
		maxSize: 500, // 限制上传文件大小(单位：Mb)。
	});
	const params = mpHelper.createUploadParams();
	params['host'] = alioss.ossConfig.host
	params['ROOT_dir'] = ROOT_dir
	filePath = ROOT_dir + '/' + filePath
	let outNetPath = 'https://' + alioss.ossConfig.host + '/' + filePath
	let result = await db_addOne(
		'UploadRecord', {
			uid,
			fileId,
			fileName,
			filePath,
			outNetPath,
			isValid: 0,
			fileSize,
			fileType,
			uploadTime,
			ShowRecordIndDvice: {
				Android: true,
				pc: true,
				iOS: true,
				recycleIn: false
			}
		},
	)
	if (result.id) { // 文档就这么写的有ID值就ok
		return {
			msg: "添加上传记录成功~",
			code: 200,
			params
		}
	}
	return {
		msg: "内部错误~",
		code: 500
	}
}
// 上传接口（同步记录调用的）
exports.APISyncUploadFile = async function(body_data) {
	let {
		fileId,
		progress,
		isValid
	} = body_data;
	// if(progress===0) progress == '0'
	if (!fileId) {
		return {
			msg: "参数错误"
		}
	};
	isValid = 1
	if (progress == 100) {
		isValid = 2
	}
	let result = await db_update_where('UploadRecord', fileId, {
		isValid,
		progress,
		SyncTime: new Date()
	})
	// 更新成功~
	if (result.updated > 0) {
		return {
			msg: "同步上传记录成功~",
			code: 200
		}
	}
	return {
		msg: "内部错误~",
		code: 500,
		result
	}
}
// 删除上传记录（删除安卓设备的） //TODO  后期接口优化 上传设备信息
exports.APIDelUploadRecord = async function(body_data) {
	let {
		fileId
	} = body_data;
	if (!fileId) {
		return {
			msg: "参数错误"
		}
	};
	let result = await db_update_where('UploadRecord', fileId, {
		ShowRecordIndDvice: {
			Android: false
		}
	})
	// 更新成功~
	if (result.updated > 0) {
		return {
			msg: "删除记录成功~",
			code: 200
		}
	}
	return {
		msg: "内部错误~",
		code: 500,
		result
	}
}
// 获取上传记录
exports.APIGetUploadRecordList = async function(body_data) {
	let {
		Token
	} = body_data;
	// 查询Token 拿路径
	let res = await db_select("User", {
		Token
	})
	if (res.data.length == 0 || res.data === null) {
		return {
			code: 211,
			msg: "Token已过期,请重新登录"
		}
	}
	let ROOT_dir = null,
		uid = null
	if (res.data.length >= 1) {
		ROOT_dir = res.data[0].account
		uid = res.data[0]._id
	}
	let result = await db.collection('UploadRecord').where({
		uid,
		isValid: 2,
		ShowRecordIndDvice: {
			Android: true
		},
	}).orderBy('uploadTime','desc').get()
	// 查询成功~
	// if (res.data.length >= 1) {
	// 	return {msg: "查询记录成功~",code: 200,result}
	// }
	return {
		msg: "查询记录成功~",
		code: 200,
		result
	}
	return {
		msg: "内部错误~",
		code: 500,
		result
	}
}
// 获取文件列表
exports.APIGetFolderList = async function(body_data) {
	let {
		dir,
		UserInfo
	} = body_data;
	let ROOT_dir = UserInfo.account
	dir = dir ? dir : ""

	// 查看指定文件夹下的所有文件及文件目录  dir：  abc/aaa/
	const result = await alioss.FolderList(ROOT_dir + '/' + dir)
	return {
		code: 200,
		path: ROOT_dir + '/' + dir,
		msg: '查询成功~',
		result
	}
}
// 删除文件 （算法）
exports.APIDelFile = async function(body_data) {
	let res = {
		code: 200,
		msg: "成功~"
	};
	let {
		dir,
		UserInfo
	} = body_data;
	if (!dir) {
		return {
			msg: "参数错误"
		}
	};
	let ROOT_dir = UserInfo.account



	let DelFilePathArr = []
	let DelFolderPathArr = []
	// 递归函数  		先查询给目录下的文件夹（然后递归遍历里面的文件一一删除）
	let SelHasFile = async (dir, type) => {
		let result = await alioss.FolderList(dir); // 查询指定oss下所有文件
		let objects = result.objects || []; // 文件
		let FolderList = result.prefixes ? result.prefixes : []; // 文件夹

		if (objects.length > 0) { // 塞文件
			for (let [inx, item] of Object.entries(objects)) {
				item.type = tools.getFileType(item.name)
				if (inx == 0 && item.type == '/') continue
				DelFilePathArr.push(item.name)
			}
		}
		if (FolderList.length > 0) { // 塞文件夹
			//*******************这边使用foreach就炸了 async await无法生效*******************//
			for (let i = 0, item; item = FolderList[i]; i++) {
				await SelHasFile(item)
				DelFolderPathArr.push(item)
			}
		}
	}

	// 判断前端传的是数组还是字符串
	if (dir instanceof Array) {
		for (let i = 0, item; item = dir[i]; i++) {
			await SelHasFile(item)
			tools.getFileType(item) === '/' ? DelFolderPathArr.push(item) : ""
		}
	} else {
		await SelHasFile(dir)
		tools.getFileType(dir) === '/' ? DelFolderPathArr.push(dir) : ""
	}

	/*
		文件夹排序 必须是从最里层开始排序删除
		
		只是换成对象数组 然后重新排序
	*/
	let newArr = []
	for (let i = 0, item; item = DelFolderPathArr[i]; i++) {
		newArr.push({
			len: item.split('/').length,
			cont: item
		})
	}
	newArr.sort((a, b) => b.len - a.len)
	DelFolderPathArr = []
	for (let i = 0, item; item = newArr[i]; i++) {
		DelFolderPathArr.push(item.cont)
	}
	DelFilePathArr.push.apply(DelFilePathArr, DelFolderPathArr)



	// OSS数据删除操作部分
	try {
		let successCodeArr = []
		for (let i = 0, item; item = DelFilePathArr[i]; i++) {
			let result = await alioss.deleteFile(item)
			if (result.res.status == 204 || result.res.status == 200) {
				successCodeArr.push(200)
			}
		}
		if (successCodeArr.filter(i => i === 200).length === DelFilePathArr.length) {
			res.code = 200;
			res.msg = '全部删除成功~';
			res.DelList = DelFilePathArr;
		} else {
			res.code = 204;
			res.msg = '部分删除成功~';
		}

	} catch (e) {
		res.code = 500;
		res.msg = '内部错误~';
	}
	return res
}
// 获取上传图片签名接口
exports.APIUploadImg = async function(body_data) {
	let {
		Token
	} = body_data;
	// 查询Token 拿路径
	let res = await db_select("User", {
		Token
	})
	if (res.data.length == 0 || res.data === null) {
		return {
			code: 211,
			msg: "Token已过期,请重新登录"
		}
	}
	let ROOT_dir = null,
		uid = null,
		uploadTime = new Date()
	if (res.data.length >= 1) {
		ROOT_dir = res.data[0].account
		uid = res.data[0]._id
	}
	const mpHelper = new alioss.MpUploadOssHelper({
		accessKeyId: alioss.ossConfig.accessKeyId,
		accessKeySecret: alioss.ossConfig.accessKeySecret,
		timeout: 1, // 限制参数的生效时间(单位：小时)。
		maxSize: 20, // 限制上传文件大小(单位：Mb)。
	});
	const params = mpHelper.createUploadParams();
	params['host'] = alioss.ossConfig.host
	params['uploadDir'] = 'uploadImg/' + ROOT_dir // 根目录 /15892023484
	return {
		msg: "获取上传图片权限成功~",
		code: 200,
		params
	}
}
// 写入上传图片记录(同步,上传成功才调用)
exports.APIUploadImgSync = async function(body_data) {
	let {
		Token,
		uploadUrl
	} = body_data;
	if (!uploadUrl) {
		return {
			msg: "参数错误"
		}
	};
	let res = await db_select("User", {
		Token
	})
	if (res.data.length == 0 || res.data === null) {
		return {
			code: 211,
			msg: "Token已过期,请重新登录"
		}
	}
	let ROOT_dir = null,
		uid = null,
		uploadTime = new Date()
	if (res.data.length >= 1) {
		ROOT_dir = res.data[0].account
		uid = res.data[0]._id
	}
	let json = {
		uid,
		imgId: tools.create_timeName(),
		imgPath: uploadUrl,
		outNetPath: 'https://' + alioss.ossConfig.host + '/' + uploadUrl,
		uploadTime
	}
	let result = await db_addOne('UploadImg', json);
	if (result.id) { // 文档就这么写的有ID值就ok
		return {
			msg: "添加上传图片成功~",
			code: 200,
			result: {
				imgId: json.imgId,
				imgUrl: json.outNetPath
			}
		}
	}
	return {
		msg: "内部错误~",
		code: 500,
		result
	}
}

// 根据id删除第三方存储数据的接口

// 获取该账户下全部指定文件类型
exports.getSpecifyTypeFile = async (body_data) => {
	let RES = {
		code: 200,
		msg: "操作成功~"
	}
	let {
		UserInfo,
		FileType,
		pageNum,
		pageSize
	} = body_data
	if (!FileType) return {
		code: 204,
		msg: "FileType字段必传"
	}
	if (FileType != 'ImgTypes' && FileType != 'ViodeoTypes' && FileType != 'AudioTypes') return {
		code: 204,
		msg: "参数错误"
	}
	let skips = pageNum * pageSize
	let OSSRes = await alioss.FolderList(UserInfo.account + '/')
	let FolederList = OSSRes.prefixes || [] // 文件夹路径 
	let FileArray = [...(OSSRes.objects.slice(1))] // 返回的所有文件数组


	// 根据跟目录拿出该文件下的所有文件类型
	let digui = async (list) => {
		for (let i = 0; i < list.length; i++) {
			let RRR = await alioss.FolderList(list[i])
			if (RRR.objects && RRR.objects.length > 0) {
				RRR.objects.forEach((item, index) => {
					index == 0 ? "" : FileArray.push(item)
				})
			}
			if (RRR.prefixes && RRR.prefixes.length > 0) {
				digui(RRR.prefixes)
			}
		}

	}
	await digui(FolederList)
	let resultArray = [] // 要返回出去的数据
	FileArray.forEach(i => {
		if (FileTypeTest[`${FileType}`]().includes(i.name.match(/[^\.]\w*$/)[0])) {
			resultArray.push(i)
		}
	})
	RES.data = resultArray
	return RES
}

// 获取指定目录的文件大小
let getSpecifiedFileSizes = async (body_data) => {
	let {account} = body_data
	if(!account) return {code:200,msg:"参数错误~"}
	let res = { 
		code:200,
		msg:"获取成功~",
		data:{
			CurrentSize:0
		}
	}
	let OssResult = await alioss.getSpecifiedFileSizes(account)
	if(!OssResult.objects) return res 
	
	OssResult.objects.forEach(i=>{
		i.name.indexOf('.')!==-1 ? res.data.CurrentSize = res.data.CurrentSize + i.size :''
	})
	
	// 遍历计算大小
	res.OssResult = OssResult
	return res
}
exports.getSpecifiedFileSizes = getSpecifiedFileSizes

